/**    
 * @Description: 博客园地址：https://www.cnblogs.com/zumengjie/      
 * @author: 顶风少年   
 * @date: 2021年4月5日 下午10:30:14
 */
package datang.dtdb.scripting;

import java.lang.reflect.Field;
import java.util.Map;

import datang.dtdb.exceptions.ParsingException;
import datang.dtdb.parsing.GenericTokenParser;
import datang.dtdb.parsing.TokenHandler;
import datang.dtdb.reflection.MetaObject;
import datang.dtdb.scripting.DynamicContext.ContextMap;
import datang.dtdb.session.Configuration;
import datang.dtdb.type.SimpleTypeRegistry;

/**
 * 纯文本的SqlNode
 */
public class TextSqlNode implements SqlNode {

	/**
	 * sql文本
	 */
	private String data = "";

	/**
	 * 纯文本的SqlNode
	 */
	public TextSqlNode(String data) {
		this.data = data;
	}

	@Override
	public boolean apply(DynamicContext context) {
		BindingTokenParser bindingTokenParser = new BindingTokenParser(context, context.getConfiguration());
		GenericTokenParser genericTokenParser = new GenericTokenParser("${", "}", bindingTokenParser);
		data = genericTokenParser.parse(data);
		context.appendSql(data);
		return true;
	}

	/**
	 * 如果文本标签中包含 ${ 说明是动态标签
	 */
	public Boolean isDynamic() {
		return data.indexOf("${") == -1 ? false : true;
	}

	private static class BindingTokenParser implements TokenHandler {
		DynamicContext context;
		Configuration configuration;

		public BindingTokenParser(DynamicContext context, Configuration configuration) {
			this.context = context;
			this.configuration = configuration;
		}

		@Override
		public String handlerToken(String token) {
			ContextMap bindings = context.getBindings();
			Object parameter = bindings.get("_parameter");
			if (parameter == null) {
				throw new ParsingException("TextSqlNode需要有入参");
			}
			try {
				// 处理入参是简单类型的情况
				if (SimpleTypeRegistry.isSimpleType(parameter.getClass())) {
					return String.valueOf(parameter);
				} else {
					MetaObject metaObject = configuration.newMetaObject(parameter);
					return metaObject.getValue(token).toString();
				}
			} catch (Exception e) {
				throw new ParsingException("设置属性失败", e);
			}
		}

	}

}
